import { AIPanel } from "./AIPanel";

export interface IAIPlugin{
    onSelectionChanged():void;
    //被添加到插件管理中
    onAdded(mgr:AIPluginMgr):void;
}

class AIInterfaceDesc{
    //接口定义字符串
    def:string; 
    depVars:{[key:string]:any}={};//key 接口中依赖的变量名字. value:接口中依赖的变量名对应的对象
}
export class AIPluginMgr{
    aiPlugins:IAIPlugin[]=[]
    //接口片段
    interfaces:{[key:string]:AIInterfaceDesc}={}
    //接口定义字符串
    scriptDefine:string;
    //接口依赖的函数的形参数，逗号分开的列表
    vars:string;
    //接口依赖的对象，需要作为函数实参
    values:any[];

    constructor(){
        //this.updateContext();
    }

    regAIPlugin(name:string, obj:IAIPlugin){
       this.aiPlugins.push(obj);
       obj.onAdded(this);
    }

    onSelectionChanged(){
        this.aiPlugins.forEach(p=>{
            p.onSelectionChanged();
        })
    }

    updateContext(){
        let allinterface=this.interfaces;
        this.scriptDefine='';
        let names:string[]=[];
        this.values=[];

        for( let m in allinterface){
            let vars = allinterface[m];
            this.scriptDefine+=vars.def+'\n';
            if(vars.depVars){
                for( let i in vars.depVars){
                    //let {name,obj}=vars.depVars[i];
                    names.push(i);
                    this.values.push(vars.depVars[i]);
                }
            }
        }
        this.vars=names.join(',');
    }    

    runjs(str:string):Promise<any>{
        //global要展开，其他直接.
        //为了能执行await, 需要创建一个async函数
        let F = (0,eval)(`async (${this.vars})=>{
            ${str}
        }`); 
        return (F.apply(null,this.values) as Promise<any>).catch(e=>{
            AIPanel.ins.addMsg('出问题了，建议重试，或者换一种表达后再试一下。');
        });
    }
    

    /**
     * 设置本插件的接口定义
     * @param id 
     * @param def 
     */
    setAIInterface(id:string, defstring:string,dependVars:{[key:string]:any}=null){
        let i = new AIInterfaceDesc();
        i.def=defstring;
        i.depVars = dependVars;
        this.interfaces[id]=i;
        this.updateContext();
    }
}

